﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using TerminationCall.Core;

namespace TerminationCall.Editor.Logic {
    public class AutoborderEraserPainter : IPainter {

        private List<PaintTile> _paintTiles;

        public EditorToolManager EditorToolManager {
            set;
            private get;
        }

        public PaintTile[] PaintTiles(Point location) {

            _paintTiles = new List<PaintTile>();

            int x = location.X;
            int y = location.Y;

            Field field = EditorToolManager.GetSingleField(location.X, location.Y);

            if (field == null) {
                return _paintTiles.ToArray();
            }

            _paintTiles.Add(EditorToolManager.SetNullTile(location.X, location.Y));

            SetTopTile(location.X, location.Y);
            SetBottomTile(location.X, location.Y);
            SetLeftMiddleTile(location.X, location.Y);
            SetRightMiddleTile(location.X, location.Y);

            SetLeftTopTile(location.X, location.Y);
            SetRightTopTile(location.X, location.Y);
            SetLeftBottomTile(location.X, location.Y);
            SetRightBottomTile(location.X, location.Y);

            return _paintTiles.ToArray();
        }

        private void SetRightBottomTile(int x, int y) {

            x = x + 1;
            y = y + 1;

            Field field = EditorToolManager.GetSingleField(x, y);

            Tile parentTile = null;

            if (field == null) {
                return;
            }

            if (field.TileField.GetTile(TileFields.MiddleTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.MiddleTile);
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.MiddleTile));
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, parentTile.ChildTileField.GetTile(TileFields.TopTile), TileFields.TopTile));
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, parentTile.ChildTileField.GetTile(TileFields.LeftMiddleTile), TileFields.LeftMiddleTile));
            }

            if (field.TileField.GetTile(TileFields.BottomTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.BottomTile).ParentTile;
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.BottomTile));
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, parentTile.ChildTileField.GetTile(TileFields.LeftBottomTile), TileFields.LeftBottomTile));
            }

            if (field.TileField.GetTile(TileFields.RightMiddleTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.RightMiddleTile).ParentTile;
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.RightMiddleTile));
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, parentTile.ChildTileField.GetTile(TileFields.RightTopTile), TileFields.RightTopTile));
            }

            if ( field.TileField.GetTile(TileFields.RightBottomTile) != null ) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.RightBottomTile));
            }
        }

        private void SetLeftBottomTile(int x, int y) {

            x = x - 1;
            y = y + 1;

            Field field = EditorToolManager.GetSingleField(x, y);

            Tile parentTile = null;

            if (field == null) {
                return;
            }

            if (field.TileField.GetTile(TileFields.MiddleTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.MiddleTile);
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.MiddleTile));
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, parentTile.ChildTileField.GetTile(TileFields.TopTile), TileFields.TopTile));
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, parentTile.ChildTileField.GetTile(TileFields.RightMiddleTile), TileFields.RightMiddleTile));
            }

            if (field.TileField.GetTile(TileFields.BottomTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.BottomTile).ParentTile;
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.BottomTile));
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, parentTile.ChildTileField.GetTile(TileFields.RightBottomTile), TileFields.RightBottomTile));
            }

            if (field.TileField.GetTile(TileFields.LeftMiddleTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.LeftMiddleTile).ParentTile;
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.LeftMiddleTile));
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, parentTile.ChildTileField.GetTile(TileFields.LeftTopTile), TileFields.LeftTopTile));
            }

            if (field.TileField.GetTile(TileFields.LeftBottomTile) != null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.LeftBottomTile));
            }
        }

        private void SetRightTopTile(int x, int y) {

            x = x + 1;
            y = y - 1;

            Field field = EditorToolManager.GetSingleField(x, y);

            Tile parentTile = null;

            if (field == null) {
                return;
            }

            if (field.TileField.GetTile(TileFields.MiddleTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.MiddleTile);
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.MiddleTile));
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, parentTile.ChildTileField.GetTile(TileFields.BottomTile), TileFields.BottomTile));
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, parentTile.ChildTileField.GetTile(TileFields.LeftMiddleTile), TileFields.LeftMiddleTile));
            }

            if (field.TileField.GetTile(TileFields.TopTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.TopTile).ParentTile;
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.TopTile));
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, parentTile.ChildTileField.GetTile(TileFields.LeftTopTile), TileFields.LeftTopTile));
            }

            if (field.TileField.GetTile(TileFields.RightMiddleTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.RightMiddleTile).ParentTile;
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.RightMiddleTile));
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, parentTile.ChildTileField.GetTile(TileFields.RightBottomTile), TileFields.RightBottomTile));
            }

            if (field.TileField.GetTile(TileFields.RightTopTile) != null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.RightTopTile));
            }
        }

        private void SetLeftTopTile(int x, int y) {

            x = x - 1;
            y = y - 1;

            Field field = EditorToolManager.GetSingleField(x, y);

            Tile parentTile = null;

            if (field == null) {
                return;
            }

            if (field.TileField.GetTile(TileFields.MiddleTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.MiddleTile);
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.MiddleTile));
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, parentTile.ChildTileField.GetTile(TileFields.BottomTile), TileFields.BottomTile));
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, parentTile.ChildTileField.GetTile(TileFields.RightMiddleTile), TileFields.RightMiddleTile));
            }

            if (field.TileField.GetTile(TileFields.TopTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.TopTile).ParentTile;
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.TopTile));
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, parentTile.ChildTileField.GetTile(TileFields.RightTopTile), TileFields.RightTopTile));
            }

            if (field.TileField.GetTile(TileFields.LeftMiddleTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.LeftMiddleTile).ParentTile;
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.LeftMiddleTile));
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, parentTile.ChildTileField.GetTile(TileFields.LeftBottomTile), TileFields.LeftBottomTile));
            }

            if (field.TileField.GetTile(TileFields.LeftTopTile) != null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.LeftTopTile));
            }
        }

        private void SetTopTile(int x, int y) {

            y = y - 1;

            Field field = EditorToolManager.GetSingleField(x, y);
            Field topField = EditorToolManager.GetSingleField(x, y - 1);

            Tile parentTile = null;
            TileFields tileFields = TileFields.BottomTile;

            if (field == null) {
                return;
            }
            if (topField == null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null));
                return;
            }

            if (field.TileField.GetTile(TileFields.MiddleTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.MiddleTile);
                tileFields = TileFields.BottomTile;
            }
            if (field.TileField.GetTile(TileFields.LeftMiddleTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.LeftMiddleTile).ParentTile;
                if (field.TileField.GetTile(TileFields.BottomTile) == parentTile.ChildTileField.GetTile(TileFields.BottomTile)) {
                    _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.LeftMiddleTile));
                    parentTile = null;
                } else {
                    tileFields = TileFields.LeftBottomTile;
                }
            }
            if (field.TileField.GetTile(TileFields.RightMiddleTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.RightMiddleTile).ParentTile;
                if (field.TileField.GetTile(TileFields.BottomTile) == parentTile.ChildTileField.GetTile(TileFields.BottomTile)) {
                    _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.RightMiddleTile));
                    parentTile = null;
                }
                tileFields = TileFields.RightBottomTile;
            }

            if (field.TileField.GetTile(TileFields.TopTile) != null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.TopTile));
            }
            if (field.TileField.GetTile(TileFields.LeftTopTile) != null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.LeftTopTile));
            }
            if (field.TileField.GetTile(TileFields.RightTopTile) != null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.RightTopTile));
            }

            if (parentTile != null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.MiddleTile));
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, parentTile.ChildTileField.GetTile(tileFields), tileFields));
            }
        }

        private void SetBottomTile(int x, int y) {

            y = y + 1;

            Field field = EditorToolManager.GetSingleField(x, y);
            Field bottomField = EditorToolManager.GetSingleField(x, y + 1);

            Tile parentTile = null;
            TileFields tileFields = TileFields.BottomTile;

            if (field == null) {
                return;
            }
            if (bottomField == null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null));
                return;
            }

            if (field.TileField.GetTile(TileFields.MiddleTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.MiddleTile);
                tileFields = TileFields.TopTile;
            }
            if (field.TileField.GetTile(TileFields.LeftMiddleTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.LeftMiddleTile).ParentTile;
                // Bottom
                if (field.TileField.GetTile(TileFields.TopTile) == parentTile.ChildTileField.GetTile(TileFields.TopTile)) {
                    _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.LeftMiddleTile));
                    parentTile = null;
                } else {
                    tileFields = TileFields.LeftTopTile;
                }
            }
            if (field.TileField.GetTile(TileFields.RightMiddleTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.RightMiddleTile).ParentTile;

                if (field.TileField.GetTile(TileFields.TopTile) == parentTile.ChildTileField.GetTile(TileFields.TopTile)) {
                    _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.RightMiddleTile));
                    parentTile = null;
                } else {
                    tileFields = TileFields.RightTopTile;
                }
            }

            if (field.TileField.GetTile(TileFields.BottomTile) != null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.BottomTile));
            }
            if (field.TileField.GetTile(TileFields.LeftBottomTile) != null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.LeftBottomTile));
            }
            if (field.TileField.GetTile(TileFields.RightBottomTile) != null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.RightBottomTile));
            }

            if (parentTile != null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.MiddleTile));
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, parentTile.ChildTileField.GetTile(tileFields), tileFields));
            }

        }

        private void SetRightMiddleTile(int x, int y) {

            x = x + 1;

            Field field = EditorToolManager.GetSingleField(x, y);
            Field rightMiddleTile = EditorToolManager.GetSingleField(x + 1, y);

            Tile parentTile = null;
            TileFields tileFields = TileFields.BottomTile;

            if (field == null) {
                return;
            }
            if (rightMiddleTile == null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null));
                return;
            }

            if (field.TileField.GetTile(TileFields.MiddleTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.MiddleTile);
                tileFields = TileFields.LeftMiddleTile;
            }
            if (field.TileField.GetTile(TileFields.TopTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.TopTile).ParentTile;
                if (field.TileField.GetTile(TileFields.LeftMiddleTile) == parentTile.ChildTileField.GetTile(TileFields.LeftMiddleTile)) {
                    _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.TopTile));
                    parentTile = null;
                } else {
                    tileFields = TileFields.LeftTopTile;
                }
            }
            if (field.TileField.GetTile(TileFields.BottomTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.BottomTile).ParentTile;
                if (field.TileField.GetTile(TileFields.LeftMiddleTile) == parentTile.ChildTileField.GetTile(TileFields.LeftMiddleTile)) {
                    _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.BottomTile));
                    parentTile = null;
                } else {
                    tileFields = TileFields.LeftBottomTile;
                }
                tileFields = TileFields.LeftBottomTile;
            }

            if (field.TileField.GetTile(TileFields.RightMiddleTile) != null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.RightMiddleTile));
            }
            if (field.TileField.GetTile(TileFields.RightTopTile) != null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.RightTopTile));
            }
            if (field.TileField.GetTile(TileFields.RightBottomTile) != null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.RightBottomTile));
            }

            if (parentTile != null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.MiddleTile));
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, parentTile.ChildTileField.GetTile(tileFields), tileFields));
            }

        }

        private void SetLeftMiddleTile(int x, int y) {

            x = x - 1;

            Field field = EditorToolManager.GetSingleField(x, y);
            Field leftMiddleTile = EditorToolManager.GetSingleField(x - 1, y);

            Tile parentTile = null;
            TileFields tileFields = TileFields.BottomTile;

            if (field == null) {
                return;
            }
            if (leftMiddleTile == null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null));
                return;
            }

            if (field.TileField.GetTile(TileFields.MiddleTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.MiddleTile);
                tileFields = TileFields.RightMiddleTile;
            }
            if (field.TileField.GetTile(TileFields.TopTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.TopTile).ParentTile;
                if (field.TileField.GetTile(TileFields.RightMiddleTile) == parentTile.ChildTileField.GetTile(TileFields.RightMiddleTile)) {
                    _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.TopTile));
                    parentTile = null;
                } else {
                    tileFields = TileFields.RightTopTile;
                }
            }
            if (field.TileField.GetTile(TileFields.BottomTile) != null) {
                parentTile = field.TileField.GetTile(TileFields.BottomTile).ParentTile;
                if (field.TileField.GetTile(TileFields.RightMiddleTile) == parentTile.ChildTileField.GetTile(TileFields.RightMiddleTile)) {
                    _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.BottomTile));
                    parentTile = null;
                } else {
                    tileFields = TileFields.RightBottomTile;
                }
            }

            if (field.TileField.GetTile(TileFields.LeftMiddleTile) != null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.LeftMiddleTile));
            }
            if (field.TileField.GetTile(TileFields.LeftTopTile) != null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.LeftTopTile));
            }
            if (field.TileField.GetTile(TileFields.LeftBottomTile) != null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.LeftBottomTile));
            }

            if (parentTile != null) {
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, null, TileFields.MiddleTile));
                _paintTiles.Add(EditorToolManager.SetSingleTile(x, y, parentTile.ChildTileField.GetTile(tileFields), tileFields));
            }
        }        
    }
}
